/***************************************************************/
//map has a 2d array of MapPoints, each with a type. Controls the...well, the map. Oh, and the enemies
// Tyler Wozniak & Andrew Hall
/***************************************************************/

#pragma once
//#include <string>
//#include <iostream>
//using namespace std;
#include "imports.h"
#include "Enemy.h"

#define MAX_MAP 50
class Map
{
public:
	Map(const Map& other); 
	Map(void);
	~Map(void);
	enum tileType { FLOOR, WALL, DOOR_OPEN, DOOR_CLOSE, STAIR_UP, STAIR_DOWN };

#pragma region MapPoint Struct
	struct MapPoint
	{
		bool seen;//Whether or not it's been seen before
		bool visible;//Whether or not it's visible now
		bool solid;//Whether or not it blocks movement
		tileType type;//The type of tile at this point

		MapPoint()
		{
			setType(WALL);
			seen = false;
			visible = false;
		}
		MapPoint(tileType inType)
		{
			setType(inType);
			seen = false;
			visible = false;
		}

		//Sets the type and updates solidity
		void setType(tileType inType)
		{
			switch(inType)
			{
			case FLOOR:
				solid = false; 
				type = inType; break;
			case WALL:
				solid = true;
				type = inType; break;
			case DOOR_OPEN:
				solid = false;
				type = inType; break;
			case DOOR_CLOSE:
				solid = true;
				type = inType; break;
			case STAIR_UP:
				solid = false;
				type = inType; break;
			case STAIR_DOWN:
				solid = false;
				type = inType; break;
			}
		}

		MapPoint& operator=(int i)
		{
			this->setType(tileType(i));
			return *this;
		}

		operator char()
		{
			switch(type)
			{
			case FLOOR:
				return '.';
			case WALL:
				return '#';
			case DOOR_OPEN:
				return '+';
			case DOOR_CLOSE:
				return '=';
			case STAIR_UP:
				return '\\';
			case STAIR_DOWN:
				return '/';
			}
			return ' ';
		}
	};
#pragma endregion

	void updateVisible(int heroRow, int heroCol);
	void initializeMap(string inpPath);
	MapPoint getMapPoint(int row, int col) const;
	void setSeen(int row, int col);
	int checkPosition(int row, int col) const;
	Enemy* getEnemy(int index) const;
	void killEnemy(Enemy* enemy);
	vector<Unit*> getNearbyEnemyPtrs(int rng, int playX, int playY);
	void populateMap();
	bool noMoreEnemies();

	//void printMap();
private:
	//Enum for the type of tile
	List<Enemy*> enemies; //My generic List of enemies
	MapPoint** mapArray; //Array of mappoint structs
	static const int MAX_SIGHT_SQUARED = 49; //Max sight of player, squared
	static const int MAX_SIGHT = 7; //Max sight of player, not square
};
